package pf.java.pfHelperBackup;

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

public abstract class TreeListItemT<T extends TreeListItemT<T>> {

    private List<T> _children;
    
    //public List<T> Children { get { return _children ?? (_children = new List<T>()); } set { _children = value; } }

    /// <summary>
    /// 深度优先递归
    /// </summary>
    /// <param name="action">参数:T子项,int深度</param>
    public List<T> GetChildren() {
    	if(_children==null) {_children = new ArrayList<T>();}
		return _children;
	}

	public void SetChildren(List<T> children) {
		this._children = children;
	}

	public void EachChild(BiConsumer<T, Integer> action)
    {
		DoEachChild(action,2);
    }
	protected void DoEachChild(BiConsumer<T, Integer> action, int depth)
    {
		List<T> Children=GetChildren();
		for(int i=0;i<Children.size();i++) {
			T a=Children.get(i);
			action.accept(a, depth);
			a.DoEachChild(action, depth + 1);
		}
    }

    /// <summary>
    /// 深度优先递归
    /// </summary>
    /// <param name="action">参数:T子项,int深度,T父节点</param>
    public void EachChild(PFAction<T, Integer, TreeListItemT<T>> action)
    {
    	DoEachChild(action,2);
    }
    protected void DoEachChild(PFAction<T, Integer, TreeListItemT<T>> action, int depth )
    {
		List<T> Children=GetChildren();

		for(int i=0;i<Children.size();i++) {
			T a=Children.get(i);
			action.go(a, depth, this);
			a.DoEachChild(action, depth + 1);
		}		
    }

    /// <summary>
    /// 深度优先递归
    /// </summary>
    public void EachChild(Consumer<T> action)
    {
		List<T> Children=GetChildren();

		for(int i=0;i<Children.size();i++) {
			T a=Children.get(i);
			action.accept(a);
			a.EachChild(action);
		}	
    }

    /// <summary>
    /// 遍历末级叶节点
    /// </summary>
    /// <param name="action"></param>
    public void EachLeaf(Consumer<T> action)
    {
		List<T> Children=GetChildren();

		for(int i=0;i<Children.size();i++) {
			T a=Children.get(i);

            if (a.GetChildren().size()>0)
            {
                a.EachLeaf(action);
            }
            else
            {
            	action.accept(a);
            }
		}			
    }
    /// <summary>
    /// 第一个叶节点
    /// </summary>
    public T FirstLeaf(Function<T, Boolean> condition)
    {
		List<T> Children=GetChildren();
        if (Children.size() < 1) { return condition.apply((T)this) ? (T)this : null; }
        T result;
        for (T i : Children)
        {
            result = i.FirstLeaf(condition);
            if (result != null) { return result; }
        }
        return null;
    }


    //#region 便于过滤所需要的变量,请不要在外部使用
    protected TreeListItemT<T> _parent = null;
    protected Boolean _fitFilter = false;
    private void SetParent()
    {
        EachChild((child, depth, parent) ->
        {
            child._parent = parent;
            child._fitFilter = false;
        });
    }
    protected void SetFit()
    {
        this._fitFilter = true;
        if (this._parent != null) { _parent.SetFit(); }
    }
    protected void RemoveNotFit()
    {
		List<T> Children=GetChildren();
		
        for (int i = Children.size() - 1; i >= 0; i--)
        {
        	T ChildrenI=Children.get(i);
            if (ChildrenI._fitFilter)
            {
            	ChildrenI.RemoveNotFit();
            }
            else
            {
                Children.remove(ChildrenI);
            }
        }
    }
    //#endregion

    /// <summary>
    /// 根据叶节点来过滤
    /// </summary>
    public TreeListItemT<T> FilterByLeaf(Function<T, Boolean> condition)
    {
        SetParent();
        EachLeaf((a) -> {
            if (condition.apply(a))
            {
                a.SetFit();
            }
        });
        RemoveNotFit();
        return this;
    }

    /// <summary>
    /// 获得最大深度(最小为1)
    /// </summary>
    /// <returns></returns>
    public int GetDepth()
    {
         int max = 1;
         int[] arr = new int[]{max};
        EachChild((a, b) -> { 
        	//if (b > max) { max =b.intValue(); }//报错:Local variable max defined in an enclosing scope must be final or effectively final
        	if (b > arr[0]) { arr[0] =b.intValue(); }
        	});
        max=arr[0];
        return max;
    }


    /// <summary>
    ///     获得所有children的数量,递归查找
    /// </summary>
    /// <returns></returns>
    public int GetAllChildrenCount()
    {
        int total = 0;
        int[] arr = new int[]{total};
        EachChild(a -> arr[0]++);
        total=arr[0];
        return total;
    }

    /// <summary>
    /// 获得所有末级叶Child的数量
    /// </summary>
    /// <returns></returns>
    public int GetAllLeafCount()
    {
        int total = 0;
        int[] arr = new int[]{total};
        EachLeaf(a -> arr[0]++);
        total=arr[0];
        return total;
    }
    /// <summary>
    /// 获得所有末级叶Child的数量
    /// </summary>
    /// <returns></returns>
    public int GetAllLeafCount(Function<T, Boolean> condition)
    {
        int total = 0;
        int[] arr = new int[]{total};
        EachLeaf(a -> { if (condition == null || condition.apply(a)) { arr[0]++; } });
        total=arr[0];
        return total;
    }
}
